home *** CD-ROM | disk | FTP | other *** search
/ PC Gamer (Italian) 33 / PC Gamer IT CD 33 2-2.iso / DINKDEMO / ADDONS / dink104.exe / DINKC.TXT < prev    next >
Text File  |  1998-03-30  |  40KB  |  1,108 lines

  1. DINKC reference.
  2.  
  3. For info on DINKEDIT.EXE, check TUT1.TXT, is a tutorial on how to use
  4. it to create your own addon/adventure.
  5.  
  6. This file is an attempt to give detailed information on every DinkC command.
  7.  
  8. Creating DINK addons isn't for beginners - at least some programming
  9. experience is required, hopefully in C.  Although studying included .C
  10. files might be enough...
  11.  
  12. In any case, I hope to continue to improve the system and language and offer
  13. tutorials and other help files to make creating new worlds for Dink an easier
  14. process.
  15.  
  16. Please visit http:  www.rtsoft.com to find the latest Dink info and
  17. developement tools/info.
  18.  
  19. If you have any questions or comments, feel free to email me, mime encoded
  20. file attachments are ok if you'd like me to check out something you are
  21. doing.  Unless I get totally busy I'll have time for everyone.
  22.  
  23. I really enjoy helping and I believe that the more creative minds that use
  24. this system to bring their own story and characters to life, the better.
  25.  
  26. Thanks,
  27.  
  28. Seth Able Robinson
  29. email: sethable@rtsoft.com
  30.  
  31.  
  32.   Part 1:  DinkC - what is it?
  33.   Part 2:  List of internal procedures
  34.   Part 3:  A changing world
  35.   Part 4:  How items work
  36.   Part 6:  How the choice commands work
  37.   Part 5:  Advanced techniques
  38.   Part 7:  Known limitations
  39.                                  PART 1
  40.  
  41.                        -= DINKC - WHAT IS IT? =-
  42.  
  43.   Ok, it is a scripting language.  I created a simular language for a
  44.   door game I wrote called LORD2, and I got a LOT of email about what people
  45.   liked and didn't like so I made this one better.  A lot better.
  46.  
  47.   DinkC supports:
  48.  
  49.   * The format is in standard C/C++ for the most part
  50.   * Nested loops thousands of levels deep
  51.   * Procedural structure support, limited only by stack
  52.   * Both local and global dynamic variable creation with custom names. All
  53.     GLOBALS you create are saved with the player data file automatically.
  54.   * Attaching a DinkC script to an object, person or monster - giving it's
  55.     own brain.
  56.   * Up to 200 DinkC scripts can be running AT THE SAME TIME.
  57.   * Memory for scripts and other things are dynamically created and
  58.     destroyed continuously.  Blank spaces in the .C file ect will not
  59.     waste space.
  60.   * Powerfull callback functions to tell Dink when to run your script
  61.   * If an object has a script associated with it (done in DinkEdit) if
  62.     hit, talked to, killed ect it will automatically look in its script
  63.     for a hit(), die(), attack() or talk() procedure.
  64.   * Run with /DEBUG Dink.exe will report all errors/debug strings in DEBUG.TXT
  65.   * Compilable with compile.exe, file gets smaller and encrypted.
  66.  
  67.  
  68.  
  69. *** THE COMMANDS ***
  70.  
  71. When a Dinkc file is associated with a sprite, a function called main() is
  72. loaded and run when the screen is loaded.  This is where you establish
  73. when what procedures will be called when.
  74.  
  75. Map screens can also be associated with a sprite, this is run before the
  76. screen is drawn and the sprites are created. (¤t_sprite and sp() don't
  77. work yet, because no sprites exist!
  78.  
  79. Even though the syntax is C/C++, there are many differences, most are to
  80. make writing dinkscripts easier, such as all var names must start with
  81. &, but you can put a var name in the middle of any string and it will be
  82. deciphered correctly.
  83.  
  84. For instance:
  85.  
  86. Say("You have &life life points, dink.", ¤t_sprite);
  87.  
  88. Would make the NPC say:
  89.  
  90. "You have 15 life points, dink."
  91.  
  92. This is true of all variables, no matter what type.
  93.  
  94.  
  95.                                 PART 2
  96.  
  97.                  -=  THE LIST OF INTERNAL PROCEDURES  =-                     
  98.  
  99. make_global_int( char nameofvar[20], int default_value);
  100.  
  101.     this makes a global int - the default_value is only given to it if
  102.     this is the first time it has been initted and doesn't exist already in
  103.     the saved game file. (usually these are in the main.c file)
  104.  
  105. int &junk;
  106. int &crapvar = 0;
  107. int &num = sp(12);
  108. int &nummy = random(100,1);
  109.  
  110.   The int statement creates a variable accessable ONLY to the current
  111.   instance of the current script.  It differs from C in one way:  The scope
  112.   of an int in DinkC is the ENTIRE script.  Any procedure in the script can
  113.   see/use this var.
  114.  
  115. int random(max, plus_this);
  116.  
  117.   Random(10,1) would return a number between 1 and 10.  Random(5,0) would
  118.   return a number from 0 to 4.  Simular to how C does it.
  119.  
  120. int scripts_used();
  121.  
  122.   Returns the # of scripts being used right now.  If > 190 or so, you
  123.   probably don't want to create any more until the guy moves to another
  124.   screen or something.
  125.  
  126. int inside_box(int x, int y, int left, int up, int right, int down);
  127.  
  128. //is the x and y cord inside this box?  Returns 1 if yes.
  129.  
  130. int busy(int sprite);
  131.  
  132.   returns 0 if this sprite is not 'talking' to someone.  Else it returns
  133.   the sprite # of the speech.
  134.  
  135. if (&life > 5) &life = 0;
  136. if (random(10,1) != 1)
  137.    {
  138.     say("The number is not 1!",1);
  139.    } else
  140.    {
  141.     say("The number IS 1!",1);
  142.    }
  143.  
  144.    works like a standard if statement
  145.  
  146. debug( char string[200] );
  147.  
  148.   Writes to the debug.txt file if the -debug parm is set when dink.exe
  149.   is run.  Var names can be used inside the string.
  150.  
  151. initfont( char string[200] );
  152.  
  153.   Dink will change to this font.  Default is Arial.  You can change fonts
  154.   as many times as you want.  This was included so international translations
  155.   would be easier.
  156.  
  157. void say(char string[200], int sprite);
  158.  
  159.   Says the string above the sprite you wish.  Use ¤t_sprite to
  160.   choose the 'owner' of the script.  (assuming it is attached to a
  161.   sprite)
  162.   If sprite was already talking, the old text will be erased. (so they
  163.   don't overlap)
  164.   If sprite is 1000, this will be a 'text only' say, not attached to a
  165.   sprite.  If this happens, you can use the return int to set it's x and
  166.   y.  1000 is used for cut scenes - it also turns off centering.
  167.  
  168.   If you need to know the SPRITE # of a certain text sprite, you can check
  169.   &last_text at anytime.
  170.  
  171. int say_xy(char string[200], int x, int y);
  172.  
  173.   Same as above except automatically attaches it to 1000 and lets you
  174.   specify X Y cordinates. (returns sprite #)
  175.  
  176.   If you specify ` (reverse apostrophy/unshifted tilde) and then a #, it
  177.   will show the text in this color.  Example:
  178.  
  179.   These are the same as LORD color codes in the BBS world.
  180.   1234567890!@#$% can be used.  (15 colors)
  181.  
  182.    say("`4Hello!", 1); (reddish)
  183.  
  184.    NOTE:  If text doesn't seem to be showing up after a `%, it's probably
  185.    because you have a I, D or J next, which are C syntax for other
  186.    things - just put a space after `% and you'll be fine.
  187.  
  188. say_stop(char string[200], int sprite);
  189.  
  190.   same as above but stops this script until the thing is said
  191.  
  192. say_stop_xy(char string[200], int x, int y);
  193.  
  194.   Same as above except automatically attaches it to 1000 and lets you
  195.   specify X Y cordinates.
  196.  
  197. say_stop_npc(char string[200], int sprite);
  198.  
  199.   Say as say_stop, but will not let the PLAYER skip things by hitting
  200.   space - if the player may be talking to someone else while this
  201.   is called, (like two girls talking in the background) you should use
  202.   this, it is safe.  Otherwise callbacks may conflict...
  203.  
  204.  
  205. wait(int amount);
  206.  
  207.   stops this script for this length in thousands of a second.
  208.  
  209. freeze(int sprite);
  210.  
  211.   this sprite now cannot move on its own.  Can still be killed though.
  212.  
  213. unfreeze(int sprite);
  214.  
  215.   to use with above, sprite can move again.
  216.  
  217. move(int sprite, int direction, int destination, int nohard);
  218.  
  219.   This sprite will move in this direction (can be 2, 4, 6 or 8) until
  220.   sprites X or Y (depending on dir) meets or exceeds 'destination'.  If
  221.   nohard is 1 then the sprite can walk through hardness, if 0 it will get
  222.   stuck on walls like normally.
  223.  
  224. move_stop(int sprite, int direction, int destination, int nohard);
  225.  
  226.   same as above but stops script until the sprite has met the destination
  227.   use carefully, if the sprite hits something, it will NEVER get to the
  228.   destination and therby the script will never be finished.  Won't cause
  229.   a game crash or anything though.  
  230.  
  231. set_callback_random(char name_of_proc[20], int min, int max);
  232.  
  233.   tells Dink to run this proc inside of the current script every
  234.   min + random (max) thousandths of a second.
  235.  
  236. goto crap;
  237.   skipping this part
  238. crap:
  239.  
  240.   Goto differs from C in one way:  The scope of a goto is the ENTIRE script.
  241.   You can 'goto' other procedures.
  242.  
  243. return;
  244.  
  245.   exits the script.  returning values (ie, return(&var) is not supported.
  246.  
  247. my_proc();
  248.  
  249.   This is how you run a procedure located in the current script.
  250.  
  251. void external(string name_of_c_file, string name_of_proc);
  252.  
  253.   This is how you run a procedure in another script.  It will return
  254.   when it is finished.  Example: external("make", "func1");
  255.  
  256.  
  257. int spawn(string name_of_c_file);
  258.  
  259.   Sort of like above - but calls it's main() and doesn't stop the script
  260.   it was called from, or affect it in any way.  Be carefull with this.. if
  261.   you create a 'spawn to infinity' loop you won't like it.
  262.  
  263.   Anything spawned this way is NOT attached to a sprite, (use sp_script if
  264.   you wish to do this) and must be killed manually when you are finished
  265.   with it, or it will ALWAYS be in memory.  (it can live past a screen
  266.   change...)  Do a kill_this_task(); to kill it when done.
  267.  
  268.   Returns the script # created.  0 if there was an error.
  269.  
  270. int sp(1);
  271.  
  272.   VERY important - this returns the actual SPRITE # of a certain EDITOR screen
  273.   object.  For instance, if you placed one tree on a screen with the editor,
  274.   you could use the above to get the sprite # of the tree.  (it would
  275.   most likely be 2, (dink is ALWAYS 1) but never guess)
  276.  
  277. int sp_editor_num(int sprite);
  278.  
  279.   the opposite of the above - returns the EDITOR # of a given sprite.  Will
  280.   return -1 if sprite did not originate from the editor.
  281.  
  282. int is_script_attached( int sprite num );
  283.  
  284.   Returns the script id # in memory attached to the sprite.  0 if none.
  285.   dam-fire.c uses to determine if a tree has something 'special' going on
  286.   with it. (so it doesn't just burn it like normal)
  287.  
  288. void run_script_by_number( int script id #, char proc_name[30]);
  289.  
  290.   For use with above basically.  You can force a script to run it's DIE
  291.   procedure for instance.
  292.  
  293. int create_sprite(int x, int y, int brain, int pseq, int pframe);
  294.  
  295.   creates a new sprite.  Returns the actual sprite #.  (uses the 1st unused slot
  296.   it can find, returns 0 if all 300 are already in use.
  297.  
  298. int get_sprite_with_this_brain( int brain, int sprite calling)
  299.  
  300.   This returns the first sprite # that is on the screen with this
  301.   brain. It will not include the sprite # sent in the second parm in the
  302.   search, so a sprite can check for 'other brains of it's type' if needed.
  303.  
  304. int get_rand_sprite_with_this_brain( int brain, int sprite calling)
  305.  
  306.   Same as above but returns a random sprite #.  Used by dragons to
  307.   target the town folk.
  308.  
  309. void init(char line[100]);
  310.  
  311.   Let's you do a line normally done in the dink.ini file.  I use this to
  312.   'replace' graphics on the fly.  (load new graphics to already used
  313.   sequences, for dink's weapons)
  314.  
  315.   Example:  init("load_sequence graphics\milli\mill- 45 100");
  316.  
  317. add_exp(int amount, int sprite_to_get_x_y_cords from);
  318.  
  319.   Let's you add experience visually correct, so the # floats above something.
  320.  
  321.  
  322. draw_hard_map( void );
  323.  
  324.   this will recalculate ALL hardness based on what is current on the
  325.   screen.  If you dynamically turn off a sprite, it will leave the screen, but
  326.   if the sprite has type 0 hardness it will still be there until this is
  327.   called.  This isn't very fast, so don't use it on a regular bases, but instead
  328.   for special things.
  329.  
  330. draw_hard_sprite( void );
  331.  
  332.   Same as above, but limited to ONE sprites hardbox.  MUCH faster then the
  333.   above.  Breaking barrels use this.
  334.  
  335. draw_background( void );
  336.  
  337.   draws the background (tiles and all type 0 sprites).  After seriously
  338.   playing with the screen (like doing a fill_screen) this can fix it up.
  339.   All dead bodies ect will be missing, so keep this in mind.
  340.  
  341. preload_seq( int sequence);
  342.  
  343.   Loads the graphic sequence if it isn't already cached somewhere.
  344.   (sequences are defined in DINK.INI)
  345.  
  346. kill_this_task( void );
  347.  
  348.   kills the current script completely.  This is rarely used, because
  349.   if a script is attached to a sprite, it will die when the sprite does
  350.   automatically.  ESCAPE.C uses this because it isn't attached to anything.
  351.   (this is run when the ESCAPE button is pressed)
  352.  
  353. kill_game( void );
  354.  
  355.   Yup, like it sounds.
  356.  
  357. fade_down( void );
  358.  
  359.   the screen will fade to black.  It's up to you to call the following
  360.   command..  The script is paused until this is accomplished, then
  361.   continued.
  362.  
  363. fade_up( void );
  364.  
  365.   yay, we can see again.  Script is paused until this is accomplished, then
  366.   continued.
  367.  
  368. void set_dink_speed( int speed)
  369.  
  370.   Let's you change dink's walking speed.  3 is normal, 2 is fast. 1 is..
  371.   I don't know, never tried it, but I'm gonna guess real fast.
  372.  
  373. void reset_timer(void)
  374.   
  375.   Sets the persons time to 0, and starts the counter from now.
  376.   (done in start-1.c, when the guy starts a new game)
  377.  
  378. force_vision( int new_vision );
  379.  
  380.   changes vision and updates screen to reflect vision changes - basically
  381.   like walking onto a new screen, but doesn't change dinks location.
  382.   warning: it kills all script and sprites and reconstructs them using
  383.   the new vision.  It also makes the script being run stay alive by
  384.   connecting it to sprite 1000 (script never dies).  You must use
  385.   kill_this_task() or it will NEVER die.
  386.  
  387. int set_mode(int mode);
  388.  
  389.   sets the mode.  You should never use this, is used for low level stuff
  390.   mode 2: This loads the players screen and draws the statbar stuff then
  391.   changes it to mode 3 automatically, which is 'regular game mode'
  392.   mode 2: In mouse selection mode (use keep_mouse if you want mouse
  393.           support INSIDE the game portion as well)
  394.   mode 3: Game is running now.
  395.  
  396. void set_keep_mouse( int O_or_1);
  397.  
  398.    Let's say you wanted curser like mouse control in your addon, set this
  399.    right after loading the game, and the mouse support will stay.  Note
  400.    that sprite one must have brain 13 for it to activate. (1 is yes)
  401.  
  402. void activate_bow( void );
  403.  
  404.   Special hack needed for the bow weapons 'charge up' time stuff.
  405.   (check item-b1.c for example)
  406.  
  407.   If you use this, keep in mind the bow animations base is 100 and is
  408.   6 frames per dir (it uses 8 directions).  This is hardcoded.
  409.  
  410. int get_last_bow_power( void );
  411.  
  412.   For use with above, the weapons script can create the arrow or whatever
  413.   according to how well they shot it.  
  414.  
  415. void screenlock( int );
  416.  
  417.   Pass this 1 to 'lock the screen'.  This means Dink cannot walk off the
  418.   screen.
  419.  
  420.   Pass 0 to change it back to normal.
  421.  
  422. void dink_can_walk_off_screen( int );
  423.  
  424.   Pass 1 and Dink can walk off the screen and not trigger a 'screen scroll'
  425.   to the next screen.  I use this for cutscenes that I want Dink to be
  426.   able to walk off the screen on.  I'm entirely tired of saying the word
  427.   screen.
  428.  
  429. void stop_entire_game( int );
  430.  
  431.   Set this to 1 and the whole game will be frozen EXCEPT for the choice
  432.   commands.  I needed this for lraise.c, people didn't much like the fact
  433.   that they had to pick where their skill points were going WHILE doing
  434.   battle...  It will unfreeze the game and set this back to 0 automatically
  435.   as soon as something is chosen.
  436.  
  437. int get_last_sprite_with_this_brain(int brain, int sprite_to_not_count );
  438.  
  439.   Helpfull with screenlock technology or any instance when you want to 
  440.   know when all enemies are dead, or you want to target an enemy of
  441.   a certain brain type.
  442.  
  443.   The 'sprite_to_not_count' parm is usually ¤t_sprite, it ignores
  444.   this sprite with doing its computation.  Use 0 otherwise.
  445.  
  446.   Check en-pill1.c for example usage.
  447.  
  448. void fill_screen(int color)
  449.  
  450.   fills the entire screen a certain color.  0 is black.
  451.  
  452. void playsound (int sound_num, min_speed, rand_speed_to_add, int sprite_or_0,
  453.                 bool repeat?)
  454.  
  455.   this plays a sound.  If rand_speed_to_add isn't 0, a random # will be
  456.   made from this # and added to the sound. If sprite isn't 0, the sound
  457.   will be 3d based on this sprites location.  If the sprite is killed
  458.   for some reason, the sound will die too.  (ie, a fire goes out)
  459.   if repeat is not 0, the sound will repeat.
  460.  
  461. void kill_shadow(int sprite);
  462.  
  463.   checks for sprites with a brain of 15 and brain_parm of 'sprite' - and
  464.   kills them.  I use this to remove shadows until projectiles when the
  465.   projectile explodes, but isn't killed.  (shadows kill themselves when
  466.   the sprite they were attached to dies)
  467.  
  468.  
  469. void hurt(int sprite, int damage);
  470.  
  471.   This let's you tell the game to hurt this sprite for a certain amount
  472.   of damage.  Defense will be calculated.  If the hit is for 0, there is
  473.   a %50 chance that it will hit the guy for 1.  (this way there are never
  474.   any 'I'm completely stuck' situations unless we purposely code them)
  475.  
  476.   Also:  If the thing is hurt blood spurts are added, free of charge.
  477.  
  478.  
  479. void script_attach(int # to attach it to);
  480.  
  481.   you can attach the current script to another sprite, (it will be
  482.   unnattached from the current one) or attach it to 1000, which means
  483.   "no sprite, will not die on it's own".  For instance, if you wanted
  484.   Dink to say "I'm poisoned" every 5 seconds for infinity, (and you didn't
  485.   want the script deleted when Dink moved to a new screen) setting it 1000
  486.   is the way to go.  You must then use kill_this_task to get rid of it, if
  487.   you don't, it will be there FOREVER.
  488.  
  489. void load_screen( void )
  490.  
  491.   loads screen
  492.  
  493. void draw_screen( void )
  494.  
  495.   draws the screen.
  496.  
  497. void draw_status( void )
  498.  
  499.   draws the status bar and side bars
  500.  
  501.   To warp someone in a script, change &player_map and then call the three
  502.   above procedures.
  503.  
  504. playmidi(char midiname[12]);
  505.  
  506. stopmidi(char midiname[12]);
  507.  
  508. stopcd( void );
  509.  
  510. ****** COMMANDS TO GET/CHANGE SPRITE ATTRIBUTES ******
  511.  
  512. A negetive # means 'do not change' in these values.
  513.  
  514. A return value of -1 means the sprite does not exist (most likely), or there
  515. was an error of some kind.  A good way to check it something is dead or not.
  516.  
  517. Example:
  518.  
  519. int &my_speed = sp_speed(1,-1);   gets the speed of dink
  520. sp_speed(1,2);   sets dinks speed to 2
  521.  
  522. int sp_speed(int sprite, int value (-1 to not change));
  523.  
  524.   speed of sprite:  If one is still too fast, see sp_timing. (max of 5);
  525.   example:  dink uses speed 1, timing 0.  (no timing delay) and moves
  526.   pretty quick.
  527.  
  528. int sp_dir(int sprite, int value (-1 to not change));
  529.  
  530.   Direction of sprite.  If this is set, the sprite will face in this
  531.   direction.  (based on what is in sp_base_walk)  If a speed is set, it
  532.   will be moving in this direction.
  533.  
  534. int sp_mx(int sprite, int value (-1 to not change));
  535.  
  536.   X movement.  If you don't want to deal with directions, or need some
  537.   kind of weird movement, this lets you specify in pixels how fast the
  538.   sprite is going.  -5 would move left. 5 would move right.
  539.  
  540. int sp_my(int sprite, int value (-1 to not change));
  541.  
  542.   Y movement.  Same deal as above basically.
  543.  
  544. int sp_disabled(int sprite, int value (-1 to not change));
  545.  
  546.   If 1, sprite is not currently disabled - it is there, but not being
  547.   drawn or moved.  I used this on the bridge, to make a hardness I
  548.   could remove quickly without wanted to deal with 'visions' in the
  549.   editor.
  550.  
  551. int sp_size(int sprite, int value (-1 to not change));
  552.  
  553.   100 is normal.  200 would make this sprite twice its size.  Sizing
  554.   can cause a large performance hit, (unless the card supports hardware
  555.   transparent scaling) so use sparingly.
  556.  
  557. int sp_hitpoints(int sprite, int value (-1 to not change));
  558.  
  559.   Hitpoints of sprite.  If 0, nothing happens when this sprite cannot die.
  560.   In both cases, if a script is assigned to the sprite, hit() and die() will
  561.   be run. (well, die is run when their hitpoints < 1, naturally)
  562.  
  563. int sp_strength(int sprite, int value (-1 to not change));
  564.  
  565.   Strength of a sprite.  If a sprite has a strength of 10, he will hit
  566.   between 6 and 10.  
  567.  
  568. int sp_defense(int sprite, int value (-1 to not change));
  569.  
  570.   Defense of a sprite - this is taken right off the top of the damage
  571.   done to them.  Someone with a defense of 20000 would likely be
  572.   invincible. <g>
  573.  
  574. int sp_exp(int sprite, int value (-1 to not change));
  575.  
  576.   How much experience someone would get if they killed 'em.  
  577.  
  578. int sp_sound(int sprite, int value (-1 to not change));
  579.  
  580.   Attaches a sound (by #) to the sprite and repeats it until the sprite
  581.   it killed.  Uses '3d' sound cueing. (forces 22kz?)
  582.  
  583. int sp_timing(int sprite, int value (-1 to not change));
  584.  
  585.   Allows you to set a delay between how often the sprites brain is called.
  586.   a delay of 33 means 30.3 times a second.  66 means.. 15.15!  Without
  587.   using this, everything would move entirely too fast.
  588.  
  589. void sp_kill(int sprite, int delay before killing);
  590.  
  591.   This lets you tell sprite to kill itself in a timed way.
  592.   sp_kill(¤t_sprite, 1000); would cause ¤t_sprite to die
  593.   in 1 second. (0 to disable, use on text to make it stay there)
  594.  
  595. void sp_kill_wait(int sprite);
  596.  
  597.   This is the delay created by sp_kill.  Sometimes you want to change
  598.   this to 0, so a sprite will react immediatly.
  599.  
  600. int sp_x(int sprite, int value (-1 to not change));
  601. int sp_y(int sprite, int value (-1 to not change));
  602.  
  603.   x and y cordinates of the sprite.  Based on their 'depth dot'. (the
  604. center of the persons foot, usually, or base of the tree)
  605.  
  606. ** ABOUT PSEQ and PFRAME **
  607.  
  608. We never say "Show pic 788 for this sprite".  Instead we tell it which
  609. sequence, then what frame.  This means you can add frames to any sequence
  610. (max of 50) and not 'throw off' any other pics/animations in the game.
  611.  
  612. PSEQ and PFRAME are the CURRENT sequence and frame that sprite is showing
  613. on the screen - if SEQ is set, this means the sprite is showing this
  614. animation.  (PFRAME will change very quickly if this is happening)
  615.  
  616. A tree or rock will not have a SEQ set to 0, meaning no sequence.  The
  617. PSEQ and PFRAME will not change in this case, you can change it to show
  618. another sprite, ect.
  619.  
  620. If you wanted the tree to suddenly burn, you would set its SEQ to whatever
  621. animation you wanted - now the PSEQ and PFRAME will automatically follow
  622. the SEQ script and run through the animation!  Based on the brain, it
  623. could repeat, too.
  624.  
  625. Editting the DINK.INI file allows you to add your OWN sequences!!!
  626.  
  627. int sp_pseq(int sprite, int value (-1 to not change));
  628.  
  629.   sequence of the current pic being displayed
  630.   change this to change the sprites pic
  631.  
  632. int sp_pframe(int sprite, int value (-1 to not change));
  633.  
  634.   frame of the sequence of the current pic being displayed
  635.   change this to change the sprites pic
  636.  
  637. int sp_seq(int sprite, int value (-1 to not change));
  638.  
  639.   current sequence being used as an animation, 0 if none
  640.   change this to have the sprite play this sequence like an animation.  When
  641.   finished, it will change back to 0 unless the sprites brain is a
  642.   'repeating' brain such as a woodstove fire.
  643.  
  644. int sp_frame(int sprite, int value (-1 to not change));
  645.  
  646.   frame of the sequence of the ANIMATION this sprite is playing, not valid
  647.   if now 'seq' is set. (seq is the animation)
  648.  
  649. int sp_frame_delay(int sprite, int value (-1 to not change));
  650.  
  651.   If not 0, this forces all animations on this sprite to play at this delay
  652.   in 1000th's of a second between frames.  This lets you 'turbo charge'
  653.   monsters, so the walking anim will match the extra fast speed.
  654.  
  655. int sp_base_walk(int sprite, int value (-1 to not change));
  656.  
  657.   Should be 10, 20, 30 ect.  This means the sprite will play animations from that
  658.   base - if they walk left (direction 4, look at your numpad) it would play seq
  659.   104 if the base was 100.  All bases work this way.  If diagonals don't exist it will
  660.   use non diagonals for diagonal movement automatically, and vice versa.
  661.  
  662. int sp_base_attack(int sprite, int value (-1 to not change));
  663.  
  664.   Like base_walk but determines the sequences to use to attack.
  665.  
  666. void sp_attack_wait(int sprite, int value);
  667.  
  668.   Time in 1000ths of a seconds that you would like this monster to
  669.   forget about it's target.  
  670.  
  671. int sp_target(int sprite, int value (-1 to not change));
  672.  
  673.   This is who you want this sprite to attack.  Unless a base_attack is
  674.   set, it isn't going to do much but follow the guy around.
  675.  
  676. int sp_brain(int sprite, int value (-1 to not change));
  677.  
  678.   lets you set the brain of a sprite.  This tells the sprite how to behave, very
  679.   important!
  680.    brain 1:  Human brain.
  681.    brain 2: not used
  682.    brain 3: Duck brain.
  683.    brain 4: Pig brain.
  684.    brain 5: When seq is done, kills but leaves last frame drawn to the
  685.             background
  686.    brain 6: Repeat brain - does the active SEQ over and over.
  687.    brain 7: Same as brain 5 but does not draw last frame to the background.
  688.    brain 9: Person/monster (No diagonals)
  689.    brain 10: Person/monster (Only diagonals)
  690.    brain 11: Missile brain - repeats SEQ.
  691.    brain 12: Will shrink/grow to match size in sp_brain_parm, then die
  692.    brain 13: Mouse brain (for intro, the pointer) (do set_keep_mouse to use
  693.              inside game as well)
  694.    brain 14: Button brain.  (intro buttons, can be used in game as well)
  695.    brain 15: Shadow brain.  Shadows for fireballs ect.
  696.    brain 16: Smart People brain.  They can walk around, stop and look.
  697.    brain 17: Missile brain, but kills itself when SEQ is done.
  698.  
  699.    Info on brain 11:
  700.  
  701.    Check item-fb.c for an example of the missile brain used.  Brain_parm
  702.    and brain_parm2 can be used to set certain sprites this missile cannot
  703.    damage. (for instance, the guy who shot it and the missiles shadow
  704.    effect, if used)
  705.  
  706.    Info on brain 15:
  707.  
  708.    To use this brain, use sp_brain_parm() to set a sprite to mimic.  It
  709.    will copy this sprites location until the sprite is killed, at which
  710.    point it will kill itself.
  711.  
  712. int sp_brain_parm(int sprite, int value (-1 to not change));
  713.  
  714.   Some brains use this parm for special stuff.  Like the shrink/grow
  715.   brain. (used when they pick up an item)
  716.  
  717. int sp_reverse(int sprite, int value (-1 to not change));
  718.  
  719.   If 1, this sprite will play the SEQ's in reverse.  Usefull is some
  720.   situations, such as the opening menu we're we play the arrow animations
  721.   both ways.
  722.  
  723. void sp_touch_damage(int sprite, int value);
  724.  
  725.   If > 0 then this sprite will cause this much damage to dink if touched.
  726.   If -1, this sprite will run touch() in the sprites script if touched.
  727.   (used for picking up hearts by touch for instance)
  728.  
  729. void sp_distance(int sprite, int value);
  730.  
  731.   Set's the range of the guys weapon.  At least for Dink.. with monsters
  732.   with touch damage enabled it might do something else, can't remember.
  733.  
  734. void sp_attack_hit_sound(int sprite, int value);
  735.  
  736.   Sets the sound effect # to play when this sprite attacks and hits
  737.   something.  If 0, defaults to 9, punch. (used in item-sw1.c)
  738.  
  739. void sp_attack_hit_sound_speed(int sprite, int value);
  740.  
  741.   Sample speed to play the above sound.  Usually at 22050.  Forget to 
  742.   set this and the sound won't play...
  743.  
  744.   If > 0 then this sprite will cause this much damage to dink if touched.
  745.   If -1, this sprite will run touch() in the sprites script if touched.
  746.   (used for picking up hearts by touch for instance)
  747.  
  748.  
  749. void sp_hard(int sprite, int value);
  750.  
  751.   If 0 then this sprites hardbox will be added to the hardmap.  If 1, it
  752.   will not be.  Moving sprites should be 1.
  753.   a call to draw_hard_map() must be made to implement any changes.
  754.  
  755. int sp_active(int sprite, int value (-1 to not change));
  756.  
  757.   1 if sprite is active, 0 if not active.  You can kill a sprite using
  758.   this, or check to see if one is active.
  759.  
  760. int sp_move_nohard(int sprite, int value (-1 to not change));
  761.  
  762.   1 means this sprite will not be stopped by any hard obstacles.
  763.  
  764. int sp_flying(int sprite, int value (-1 to not change));
  765.  
  766.   1 means this sprite can move over 'low hardness' like water.
  767.  
  768. int sp_script(int sprite, char script_file_name);
  769.  
  770.   this kills any other script assigned to sprite, and attaches this new
  771.   one.  Do *NOT* include the .C extension.  It IMMEDIATLY runs this
  772.   scripts main() before continueing the current script.
  773.  
  774. int sp_que(int sprite, int value (-1 to not change));
  775.  
  776.   This is the virtical depth que for the sprite.  In most cases, it is
  777.   set to 0, which means use the Y cords of the depth dot for this.  Is some
  778.   cases, (say a cloud) you want to override this.  Change it to 1000 and it
  779.   will be 'on top' of everything.
  780.  
  781. int sp_noclip(int sprite, int value (-1 to not change));
  782.  
  783.   if 1, this sprite will not be clipped in the normal game window.  (if you
  784.   really want a sprite on the status bar, this is the way to do it..)
  785.  
  786. int sp_nodraw(int sprite, int value (-1 to not change));
  787.  
  788.   The sprite will behave like normal except for one small thing... you can't
  789.   see it. (change to 1 to activate this)
  790.  
  791. int sp_nocontrol(int sprite, int value (-1 to not change));
  792.  
  793.   if 1, this sprite cannot control himself until the current sequence he is
  794.   on is over.  This is used for dink's weapon scripts only right now.
  795.  
  796. int sp_range(int sprite, int value (-1 to not change));
  797.  
  798.   For use with missiles - increases the 'checking range'.  Put 600 and
  799.   it will hit everything on the screen, always.
  800.  
  801.  
  802.                    -= PART 3 - A CHANGING WORLD =-
  803.  
  804. We want the world to remember changes.  For instance, if Dink burns a
  805. tree down, traveled to the other end of the world and then game back, the
  806. tree should still be burned.  The same goes for taking items, breaking
  807. stuff and anything else you can think off.
  808.  
  809. How do we make the game remember?  Yes, we could assign &vars to everything
  810. and have scripts kill off what has been taken and change stuff, but this
  811. would become very tedious.. so we only do that in special spots where
  812. greater control is required.  But for little stuff, like keeping hearts
  813. we picked up from reappearing we use another system.
  814.  
  815. Screen commands issued from the players data file. (SCIFTPDF for short, ha)
  816.  
  817. The players save game file is capable of storing one parm, a seq and frame
  818. for EVERY editor sprite in the entire game.  The parm tells the draw_map
  819. command to override what the map data says and do it different.  For
  820. example, we have the barrels script do this:
  821.  
  822.   int &hold = sp_editor_num(¤t_sprite);
  823.  
  824.   if (&hold != 0)
  825.     {
  826.        this was placed by the editor, lets make the barrel stay flat
  827.      editor_type(¤t_sprite, 3); 
  828.      editor_seq(¤t_sprite, 173);
  829.      editor_frame(¤t_sprite, 4);
  830.        type means show this seq/frame combo as background in the future
  831.     }
  832.  
  833. Editor_type can be set to the following:
  834. 0 - no change
  835. 1 - kill sprite completely
  836. 2 - draw pic from enclosed seq/frame data as a sprite WITHOUT hardness
  837. 3 - draw pic from enclosed seq/frame data as a BACKGROUND object WITH
  838.     hardness (can't walk behind)
  839. 4 - draw pic from enclosed seq/frame data as a sprite WITH hardness
  840. 5 - draw pic from enclosed seq/frame data as a BACKGROUND object WITHOUT
  841.     hardness (can't walk behind)
  842. 6 - kill sprite, but let him come back after 5 minutes
  843. 7 - kill sprite, but let him come back after 3 minutes
  844. 8 - kill sprite, but let him come back after 1 minute
  845.  
  846. Seq and frame store the sequence and frame of the new sprite to be displayed,
  847. for instance, a burned tree.  The associated hardbox will be taken from
  848. the sprites info if 4 or 5 is used.
  849.  
  850. You may wish to call a draw_hard_sprite() afterward if hardness has been
  851. changed.
  852.  
  853.                    -= PART 4 - HOW ITEMS WORK =-
  854.  
  855. With DinkC, you can make unlimited items.  The only limit is Dink can only
  856. hold 16 in his inventory at one time.. this isn't because I was a lazy
  857. programmer (for once) but I believe having to manage your items and not
  858. being able to stock pile too many healing potions will actually make
  859. this a better game.
  860.  
  861. Everything here also applies to magic.  The difference between magic
  862. and items/weapons is you only have 8 magic slots, and a different button
  863. is used to activate magic.  (so, 24 items at once basically)
  864.  
  865. This means adding a new weapon that shoots an animation of your face
  866. across the screen with it's own sound effect is very easy to do!
  867.  
  868. You can COMPLETELY control the behavior of any item.  First, you need
  869. to give the player the item.
  870.  
  871. int add_item(char scriptname[8], int seq, int frame);
  872. int add_magic(char scriptname[8], int seq, int frame);
  873.  
  874. The rest is handled by the items script itself.  The best way to understand
  875. how it works is to look at item-fst.c.. but I'll explain anyway.
  876.  
  877. The sequence and frame are the picture of the item.  As soon as this is
  878. called, 'void pickup( void )' is called from the script.  If simple having
  879. this item in your inventory does something magical, this is the time to
  880. do it.
  881.  
  882. When they click on it to arm it, the script is loaded into memory and
  883. two procedures from it are called, first it looks for 'void arm( void )'
  884. and runs this.  This is where you would add 8 to the strength or makes
  885. or increased Dink's size by 50 or whatever.
  886.  
  887. Second it looks for 'void armmovie( void )' - any special thing like Dink
  888. saying "wow, I just armed so and so" is said here.  This is ONLY called
  889. if the player arms the weapon.
  890.  
  891. When the armour is DISARMED it runs 'void disarm( void )' from the
  892. items script.  Use a kill_this_task at the end of it.
  893.  
  894. Here are some other calls it will calls it will check for.  If any of these
  895. don't exist, it assumed you don't need that function and doesn't sweat it.
  896.  
  897. void use( void ) - when the button is pressed, this is called.  
  898. void holdingdrop( void ) - run when dropped and item was armed at the time.
  899.                            (drop will be run also)
  900. void drop( void ) - when item is 'dropped' this is called. 
  901.  
  902. void pickup( void ) - when item is 'picked up' this is called.
  903.  
  904. Use a kill_this_task at the end of drop() and pickup() also.
  905.  
  906. Now, there are times when you may need other commands dealing with
  907. items - so here they are.
  908.  
  909. int free_items();
  910.  
  911.    Returns how many free item spots remain.
  912.  
  913. int free_magic();
  914.  
  915.    Returns how many free magic spots remain.
  916.  
  917. int count_item(char name_of_item_script)
  918.  
  919.   Returns how many items with this script name they have.
  920.  
  921. int count_magic(char name_of_item_script)
  922.  
  923.   Returns how many items with this script name they have.
  924.  
  925. void kill_cur_item( void )
  926.  
  927.   Kills the currently armed item.  Run's it's disarm script, then drop
  928.   script.
  929.  
  930. void kill_cur_magic( void )
  931.  
  932.   Same as above but for killing the current magic equipped.
  933.  
  934. void kill_this_item( char name_of_item_script )
  935.  
  936.   Kills first instance of this item by name of script.  If it's currently
  937.   armed, it will run it's disarm and drop, otherwise it will just run the drop
  938.   script and remove it.
  939.  
  940. void kill_this_magic( char name_of_item_script )
  941.  
  942.   Same as above but applies to the magic slots.
  943.  
  944. int compare_weapon( char name_of_item_script)
  945.  
  946.    Example:  compare_weapon("ITEM-B1"); would return 1 if the armed item's
  947.              script was item-b1.  Used in s3-gobg.c.
  948.  
  949. int compare_magic( char name_of_item_script)
  950.  
  951.    Works like above.
  952.  
  953.                -= PART 5 - HOW THE CHOICE STATEMENT WORKS =-
  954.  
  955. This is the dialog box that we pop up so often.  Everything from the load
  956. game menu to talking with NPC's is done with this.  It's pretty simple
  957. to use, here is an example:
  958.  
  959. choice_start()
  960.    "Yes"
  961.    "No"
  962. choice_end()
  963.  
  964. That is all!  The result will be put into &result.  So:
  965.  
  966. if (&result == 1)
  967.   {
  968.   //said yes!
  969.   }
  970.  
  971. if (&result == 2)
  972.   {
  973.   //said no!
  974.   }
  975.  
  976. Now, lets say we want SOME options to show up, because we are too lazy
  977. to make seperate procedures for every possible combination.  Very easy:
  978.  
  979. choice_start()
  980. (&life < &lifemax)   "I need to be healed, I'm hurt"
  981. (&life >= &lifemax)  "I'm just dandy"
  982.    "Leave"
  983. choice_end()
  984.  
  985. Only two options will show up, depending on the players life.  Option 2
  986. will still return 2, even if only option 1 is listed, so you can have your IF
  987. statement check for 1 and 2, and just the chosen one will be activated.
  988.  
  989. Note:  These commands can be stacked:
  990.  
  991. (&love != 1) (&life == 5)   "Love isn't 1, and you have five life!"
  992.  
  993. The choice statement can handle up to TWENTY choices.  If this takes
  994. up more than one screen, it will automatically handly scrolling to the
  995. next screen when it needs to.
  996.  
  997. We could stop here, but there are a few more things:
  998.  
  999. You can put special commands at the top of the choice statement to change
  1000. how it looks.
  1001.  
  1002. choice_start()
  1003.         set_y 240
  1004.         set_title_color 15
  1005.         title_start();
  1006. Would you like to rock steady?
  1007.         title_end();
  1008.  
  1009.    "Yes"
  1010.    "No"
  1011. choice_end()
  1012.  
  1013. Ok, set_y sets the y cord that the choices will begin listing.
  1014. title_start() lets you specify a 'title' for the top.
  1015.  
  1016. set_title_color (optional) lets you specify what color the title is.
  1017. (you cannot change the color of the options themselves!)
  1018.  
  1019. The colors are the same as the ANSI char set if you know about BBSing...1
  1020. through 15.
  1021.  
  1022.  
  1023.                   -= PART 6 - ADVANCED TECHNIQUES =-
  1024.  
  1025. The way scripts can call other scripts, who they are connected to and
  1026. when they die is kind of like time travel - lots of theory and really
  1027. hard to understand.
  1028.  
  1029. Attaching a script to an item causes it to be run when the screen is
  1030. drawn - this is fine and dandy.  There is ANOTHER kind of script that
  1031. can be run BEFORE the screen is drawn, this is the script assocated with
  1032. the MAP SCREEN.  (done by pressing B in the map editor)
  1033.  
  1034. This script doesn't have the luxury of knowing certain info, like using
  1035. the Sp() command will always return 0, because no sprites have been drawn
  1036. yet.  However, it's a powerfull tool when used correctly, you can change
  1037. vision statements and set music BEFORE the screen is entered.
  1038.  
  1039. (you can do a wait(1) in a 'screen script', and it will draw all the sprites
  1040. and return, so you can manipulate the rest of the data)
  1041.  
  1042.                   -= PART 7 - KNOWN LIMITATIONS =-
  1043.  
  1044. Ok - try as we might, we can't be diluted into thinking DinkC is really
  1045. C.  It is an interpretated scripting language written to understand C
  1046. syntax.  To a DEGREE - here are the rules, pay attention or be prepared
  1047. to be frustrated!
  1048.  
  1049. *** Only do one command per line. ***
  1050.  
  1051. instead of
  1052. freeze(1); say("Hi",1); unfreeze(1);
  1053.  
  1054. do it like this:
  1055.  
  1056. freeze(1);
  1057. say("Hi",1);
  1058. unfreeze(1);
  1059.  
  1060. This does not waste memory.
  1061.  
  1062. DinkC PARTLY supports multiple commands per line, but later I decided not
  1063. to pursue it.. was eating up too much processer time with my slow searches..
  1064.  
  1065. **** COOL MATH NOT SUPPORTED ****
  1066.  
  1067. DinkC can only understand ONE math question at a time.
  1068.  
  1069. Dink understands:
  1070.  
  1071. ==, !=, +=, -+, >, <, >=, <=,/,*
  1072.  
  1073. Instead of:  if ( (5 + 3) > 2) ....
  1074. you must do something else such as:
  1075.  
  1076. int &crap = 5;
  1077. &crap += 3;
  1078. if (&crap > 2)
  1079.  {
  1080.  //blahblah
  1081.  }
  1082. You also cannot do:
  1083. &crap++; or &crap--.  Use &crap += 1; instead.
  1084.  
  1085. You can do:
  1086. Pap < Seth.  Grace Jones < Zorin.  Bond > OnnaTop.  K6 < p200mmx.
  1087.  
  1088. *** BE CAREFULL WITH YOUR COMMENTS ***
  1089.  
  1090. Comment like this:
  1091.  
  1092.   int &crap = 5;
  1093.   //sets this to 5, duh
  1094.  
  1095. Not like this:
  1096.   
  1097.   int &crap = 5;    //sets this to 5, duh
  1098.  
  1099. This could cause a problem, some commands use 'does this char exist in this
  1100. string?' procedures.  Don't do it.
  1101.  
  1102. If a script command is not working, turn debug mode on and study the
  1103. output - most likely you can figure what is going on from that.  If that
  1104. fails, try scripting it another way, or studying source that I have done
  1105. in the dink/story dir.
  1106.  
  1107. Note:  The COMPLETE script source is zipped up in the DEVELOP dir. (SOURCE.ZIP)
  1108.